package com.atguigu.gmall.cart.service.impl;

import com.atguigu.gmall.cart.mapper.CartMapper;
import com.atguigu.gmall.cart.service.CartAsyncService;
import com.atguigu.gmall.cart.service.CartService;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private CartAsyncService cartAsyncService;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    @Qualifier("redis")
    private RedisTemplate redisTemplate;


    public void addCart(Long skuId, Integer skuNum, String userId) {
        String cartKey = getCartKey(userId);

        QueryWrapper<CartInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        wrapper.eq("sku_id",skuId);
        CartInfo cartInfo = cartMapper.selectOne(wrapper);
        if(cartInfo!=null){
            cartInfo.setSkuNum(cartInfo.getSkuNum()+skuNum);
            cartInfo.setIsChecked(CartInfo.ISCHECKEDOK);
            cartAsyncService.updateCartInfo(cartInfo);
        }else{
            cartInfo = new CartInfo();
            cartInfo.setSkuId(skuId);
            cartInfo.setUserId(userId);
            cartInfo.setSkuNum(skuNum);
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
            cartInfo.setCartPrice(skuInfo.getPrice());
            cartInfo.setSkuName(skuInfo.getSkuName());
            cartInfo.setIsChecked(CartInfo.ISCHECKEDOK);
            cartAsyncService.saveCartInfo(cartInfo);
        }
        redisTemplate.boundHashOps(cartKey).put(skuId.toString(),cartInfo);
    }


    public CartInfo addToCart(Long skuId, String userId) {
        //在缓存中拿到数据
        CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(RedisConst.USER_KEY_PREFIX+userId+RedisConst.USER_CART_KEY_SUFFIX,skuId.toString());
        //缓存中没有则从数据库中区
        if(cartInfo==null){
            QueryWrapper<CartInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id",userId);
            wrapper.eq("sku_id",skuId);
            cartInfo = cartMapper.selectOne(wrapper);
        }
        return cartInfo;
    }
    //合并购物车
    public List<CartInfo> mergeCart(String userTempId, String userId) {
        List<CartInfo> userIdCartInfoList = getCartInfoList(userId);
        List<CartInfo> userTempIdCartInfoList = getCartInfoList(userTempId);
        //真实用户有购物车
           if(!CollectionUtils.isEmpty(userIdCartInfoList)){
               Map<Long, CartInfo> userIdCartMap = userIdCartInfoList.stream().collect(Collectors.toMap(CartInfo::getSkuId, cartInfo -> cartInfo));
                //临时用户有购物车
               if(!CollectionUtils.isEmpty(userTempIdCartInfoList)){
                   userTempIdCartInfoList.forEach(cartInfo -> {
                       CartInfo userIdCartInfo = userIdCartMap.get(cartInfo.getSkuId());
                        if(userIdCartInfo!=null){
                                userIdCartInfo.setSkuNum(cartInfo.getSkuNum()+userIdCartInfo.getSkuNum());
                                cartMapper.updateById(cartInfo);
                                cartMapper.updateById(userIdCartInfo);
                        }else{
                                cartInfo.setUserId(userId);
                                userIdCartMap.put(cartInfo.getSkuId(),cartInfo);
                                cartMapper.updateById(cartInfo);
                        }
                   });
                   redisTemplate.delete(RedisConst.USER_KEY_PREFIX+userTempId+RedisConst.USER_CART_KEY_SUFFIX);
                   return new ArrayList<>(userIdCartMap.values());
               }else{
                   //临时用户没有购物车
                   return userIdCartInfoList;
               }

           }else{
               //更新cart_info  user_id  改成真实用户的
               CartInfo cartInfo = new CartInfo();
               cartInfo.setUserId(userId);
               cartMapper.update(cartInfo,new QueryWrapper<CartInfo>()
                       .eq("user_id",userTempId));
               //清理临时用户的缓存
               redisTemplate.delete(RedisConst.USER_KEY_PREFIX +
                       userTempId + RedisConst.USER_CART_KEY_SUFFIX );
               return userTempIdCartInfoList;//显示页面购物车集合使用的
           }

    }
    //获取购物车集合
    public List<CartInfo> getCartInfoList(String userId){
        //查看缓存
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX);
        //缓存没有查看数据库
        if(CollectionUtils.isEmpty(cartInfoList)){
            cartInfoList = cartMapper.selectList(new QueryWrapper<CartInfo>().eq("user_id",userId));
        }
        cartInfoList.forEach(cartInfo -> {
            cartInfo.setSkuPrice(productFeignClient.getPrice(cartInfo.getSkuId()));
        });
        //排序
        cartInfoList.stream().sorted(((o1, o2) -> {
            return o2.getId().intValue()-o1.getId().intValue();
        }));
        return cartInfoList;
    }
    //修改选中状态
    public void checkCart(Long skuId, Integer isCkecked,String userId) {
        cartAsyncService.checkCart(skuId,isCkecked,userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(getCartKey(userId));
        if(boundHashOperations.hasKey(skuId.toString())){
            CartInfo cartInfo = boundHashOperations.get(skuId.toString());
            cartInfo.setIsChecked(isCkecked);
            boundHashOperations.put(skuId.toString(),cartInfo);
        }
    }

    //查询购物车中被用户选中的项
    public List<CartInfo> getIsCheckCartList(String userId) {
        List<CartInfo> cartInfoList = this.getCartInfoList(userId);
        List<CartInfo> isCheckedCartList = new ArrayList<>();
        cartInfoList.forEach((cartInfo -> {
            if(cartInfo.getIsChecked()==1){
                isCheckedCartList.add(cartInfo);
            }
        }));
        return isCheckedCartList;
    }

    //获取购物车的Key
    private String getCartKey(String userId){
        return RedisConst.USER_KEY_PREFIX+userId+RedisConst.USER_CART_KEY_SUFFIX;
    }
    //设置过期时间
    private void setCartKeyExpire(String cartKey){
        redisTemplate.expire(cartKey,RedisConst.USER_CART_EXPIRE, TimeUnit.SECONDS);
    }


}
